package com.shy.collect.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shy.collect.entity.PayWay;
import com.shy.collect.entity.UserPayConfig;
import com.shy.collect.entity.UserPayInfo;
import com.shy.collect.mapper.PayWayMapper;
import com.shy.collect.mapper.UserPayConfigMapper;
import com.shy.collect.mapper.UserPayInfoMapper;
import com.shy.collect.service.UserPayConfigService;
import com.shy.configs.common.enums.PublicStatus;
import com.shy.configs.common.enums.RCode;
import com.shy.configs.common.events.events.MerchConfigMailEvent;
import com.shy.configs.common.events.model.MerchConfigData;
import com.shy.configs.common.exceptions.DftException;
import com.shy.configs.common.utils.IdUtil;
import com.shy.configs.mvc.models.query.UserPayConfigQuery;
import jakarta.annotation.Resource;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

@Service
public class UserPayConfigServiceImpl implements UserPayConfigService {

    @Resource
    private UserPayConfigMapper userPayConfigMapper;
    @Resource
    private PayWayMapper payWayMapper;
    @Resource
    private UserPayInfoMapper userPayInfoMapper;
    @Resource
    private ApplicationEventPublisher eventPublisher;

    @Override
    public IPage<UserPayConfig> pageList(Integer pageNo, Integer pageSize) {
        QueryWrapper<UserPayConfig> queryWrapper = new QueryWrapper<>();
//        queryWrapper.orderByDesc("user_no", "product_code", "edit_time");
        queryWrapper.orderByDesc("edit_time");
        return userPayConfigMapper.selectPage(Page.of(pageNo, pageSize), queryWrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addPayConfig(UserPayConfigQuery userPayConfigQuery) {
        //支付产品需要有支付方式的配置
        QueryWrapper<PayWay> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("pay_product_code", userPayConfigQuery.getProductCode());
        List<PayWay> payWays = payWayMapper.selectList(queryWrapper);
        if (payWays.isEmpty()) {
            throw new DftException(RCode.PAY_WAY_NODE_ERROR);
        }
        //判断支付配置是否存在
        QueryWrapper<UserPayConfig> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("user_no", userPayConfigQuery.getUserNo()).eq("product_code", userPayConfigQuery.getProductCode());
        UserPayConfig userPayConfig = userPayConfigMapper.selectOne(queryWrapper1);
        if (userPayConfig != null) {
            throw new DftException(RCode.USER_PAY_NODE_ERROR);
        }
        //存储用户支付配置 user_pay_config表添加数据
        saveUserPayConfig(userPayConfigQuery);

        //存储user_pay_info，一个支付方式一个行记录
        saveUserPayInfo(userPayConfigQuery, payWays);


        //发生事件，异步方式
        MerchConfigData eventData = new MerchConfigData();
        eventData.setUserNo(userPayConfigQuery.getUserNo());
        eventData.setProductCode(userPayConfigQuery.getProductCode());

        MerchConfigMailEvent mailEvent = new MerchConfigMailEvent(this, eventData);
        eventPublisher.publishEvent(mailEvent);


    }

    @Override
    public List<UserPayInfo> configView(String userNo, String productCode) {
        QueryWrapper<UserPayInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_no", userNo).eq("product_code", productCode);
        return userPayInfoMapper.selectList(queryWrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deletePayConfig(String userNo, String productCode) {
        //删除user_pay_config
        QueryWrapper<UserPayConfig> configWrapper = new QueryWrapper<>();
        configWrapper.eq("user_no", userNo).eq("product_code", productCode);
        int num = userPayConfigMapper.delete(configWrapper);
        //删除user_pay_info
        if (num > 0) {
            QueryWrapper<UserPayInfo> infoWrapper = new QueryWrapper<>();
            infoWrapper.eq("user_no", userNo).eq("product_code", productCode);
            userPayInfoMapper.delete(infoWrapper);
        } else {
            throw new DftException(RCode.FAIL);
        }
    }

    /**
     * 存储user_pay_info的相关操作，一个支付方式一个行记录
     *
     * @param userPayConfigQuery
     * @param payWays
     */
    private void saveUserPayInfo(UserPayConfigQuery userPayConfigQuery, List<PayWay> payWays) {
        for (PayWay payWay : payWays) {
            QueryWrapper<UserPayInfo> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("product_code", userPayConfigQuery.getProductCode())
                    .eq("user_no", userPayConfigQuery.getUserNo())
                    .eq("pay_way_code", payWay.getWayCode());
            if (userPayInfoMapper.selectOne(queryWrapper) != null) {
                return;
            }
            //getUserPayInfo为抽取的方法
            UserPayInfo userPayInfo = getUserPayInfo(userPayConfigQuery);

            if ("KUAIQIAN".equals(payWay.getWayCode())) {
                UserPayConfigQuery.KqConfig kqConfig = userPayConfigQuery.getKqConfig();
                /*
                 * 1.kqBoolean为抽取的验证方法
                 * 2.验证快钱数据是否为空
                 * */
                if (kqBoolean(kqConfig)) {
                    //有快钱数据
                    userPayInfo.setPayWayCode("KUAIQIAN");
                    userPayInfo.setPayWayName("快钱");
                    userPayInfo.setPayConfig(JSONUtil.toJsonStr(kqConfig));
                    userPayInfo.setRemark("创建快钱支付方式");

                } else {
                    throw new DftException(RCode.USER_PAY_NONE);
                }
            } else if ("WEIXIN".equals(payWay.getWayCode())) {
                UserPayConfigQuery.WxConfig wxConfig = userPayConfigQuery.getWxConfig();
                /*
                 * 1.weixinBoolean为抽取的验证方法
                 * 2.验证微信数据是否为空
                 * */
                if (weixinBoolean(wxConfig)) {
                    //有微信数据
                    userPayInfo.setPayWayCode("WEIXIN");
                    userPayInfo.setPayWayName("微信");
                    userPayInfo.setPayConfig(JSONUtil.toJsonStr(wxConfig));
                    userPayInfo.setRemark("创建微信支付方式");
                } else {
                    throw new DftException(RCode.USER_PAY_NONE);
                }
            } else if ("ALIPAY".equals(payWay.getWayCode())) {
                UserPayConfigQuery.AlipayConfig alipayConfig = userPayConfigQuery.getAlipayConfig();
                /*
                 * 1.alipayBoolean为抽取的验证方法
                 * 2.验证支付宝数据是否为空
                 * */
                if (alipayBoolean(alipayConfig)) {
                    //有支付宝数据
                    userPayInfo.setPayWayCode("ALIPAY");
                    userPayInfo.setPayWayName("支付宝");
                    userPayInfo.setPayConfig(JSONUtil.toJsonStr(alipayConfig));
                    userPayInfo.setRemark("创建支付宝支付方式");
                } else {
                    throw new DftException(RCode.USER_PAY_NONE);
                }
            }
            userPayInfoMapper.insert(userPayInfo);
        }
    }

    /**
     * 存储user_pay_info表添加的复用的数据
     *
     * @param userPayConfigQuery
     * @return
     */

    private static UserPayInfo getUserPayInfo(UserPayConfigQuery userPayConfigQuery) {
        UserPayInfo userPayInfo = new UserPayInfo();
        userPayInfo.setId(IdUtil.uuid());
        userPayInfo.setProductCode(userPayConfigQuery.getProductCode());
        userPayInfo.setUserNo(userPayConfigQuery.getUserNo());
        userPayInfo.setShopName(userPayConfigQuery.getShopName());
        userPayInfo.setEditTime(new Date());
        userPayInfo.setStatus(PublicStatus.ENABLE.name());
        return userPayInfo;
    }

    /**
     * 微信支付配置参数验证
     *
     * @param wxConfig
     * @return
     */
    private static boolean weixinBoolean(UserPayConfigQuery.WxConfig wxConfig) {
        if (wxConfig != null && StrUtil.isNotBlank(wxConfig.getAppId())
                && StrUtil.isNotBlank(wxConfig.getMerchId())) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 微信支付配置参数验证
     */
    private static boolean alipayBoolean(UserPayConfigQuery.AlipayConfig alipayConfig) {
        if (alipayConfig != null && StrUtil.isNotBlank(alipayConfig.getAppId())
                && StrUtil.isNotBlank(alipayConfig.getMerchId())) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 快钱支付配置参数验证
     *
     * @param kqConfig
     * @return
     */
    private static boolean kqBoolean(UserPayConfigQuery.KqConfig kqConfig) {
        if (kqConfig != null && StrUtil.isNotBlank(kqConfig.getMerchId())
                && StrUtil.isNotBlank(kqConfig.getPrivateFile())
                && StrUtil.isNotBlank(kqConfig.getPublicFile())
                && StrUtil.isNotBlank(kqConfig.getQueryKey())
                && StrUtil.isNotBlank(kqConfig.getAlias())
                && StrUtil.isNotBlank(kqConfig.getAccessCode())) {
            return true;
        }
        return false;
    }

    /**
     * 存储用户支付配置 user_pay_config表添加的数据
     *
     * @param userPayConfigQuery
     */
    private void saveUserPayConfig(UserPayConfigQuery userPayConfigQuery) {
        UserPayConfig userPayConfig;
        //添加支付配置数据
        userPayConfig = new UserPayConfig();
        userPayConfig.setId(IdUtil.uuid());
        userPayConfig.setUserNo(userPayConfigQuery.getUserNo());
        userPayConfig.setShopName(userPayConfigQuery.getShopName());
        userPayConfig.setProductCode(userPayConfigQuery.getProductCode());
        userPayConfig.setProductName(userPayConfigQuery.getProductName());
        userPayConfig.setRiskDay(userPayConfigQuery.getRiskDay());
        userPayConfig.setAppKey(IdUtil.uuid());
        userPayConfig.setAppSecret(IdUtil.uuid());
        userPayConfig.setMerchantServerIp(userPayConfigQuery.getIpList());
        userPayConfig.setAutoSett("yes".equals(userPayConfigQuery.getAutoSett()) ? "YES" : "NO");
        userPayConfig.setRemark("创建支付配置");
        userPayConfig.setEditTime(new Date());
        userPayConfig.setStatus(PublicStatus.ENABLE.name());

        userPayConfigMapper.insert(userPayConfig);
    }
}
